﻿using Basic.FlowDAL;
using Basic.FlowModel.AuditLog;
using Basic.FlowModel.DB;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.FlowAudit.Model;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Basic.FlowCollect.lmpl
{
    internal class FlowAuditLogCollect : IFlowAuditLogCollect
    {
        private readonly IFlowAuditLogDAL _BasicDAL;

        public FlowAuditLogCollect ( IFlowAuditLogDAL basicDAL )
        {
            this._BasicDAL = basicDAL;
        }
        public Result[] Query<Result> ( AuditLogQuery query, IBasicPage paging, out int count ) where Result : class
        {
            return this._BasicDAL.Query<Result>(query, paging, out count);
        }

        public CreateResult Create ( AuditLogAdd add )
        {
            AuditLogState state = this._BasicDAL.Find<AuditLogState>(a => a.AppId == add.AppId && a.LinkType == add.LinkType && a.LinkPk == add.LinkPk);
            if ( state == null )
            {
                long logId = this._BasicDAL.Add(add, out long itemId);
                return new CreateResult
                {
                    ItemId = itemId,
                    LogId = logId
                };
            }
            else if ( state.Status == FlowAuditLogStatus.进行中 )
            {
                throw new ErrorException("flow.audit.already.begin");
            }
            else if ( state.IsEquals(add, true, "Status", "BeginItemId") )
            {
                return new CreateResult
                {
                    ItemId = state.BeginItemId,
                    LogId = state.Id
                };
            }
            else
            {
                long logId = this._BasicDAL.Sync(add, state.Id, out long itemId);
                return new CreateResult
                {
                    ItemId = itemId,
                    LogId = logId,
                    ToVoidId = state.Id,
                    ToVoidItemId = state.BeginItemId
                };
            }
        }
        public long Add ( AuditLogAdd add, out long itemId )
        {
            return this._BasicDAL.Add(add, out itemId);
        }


        public Result Get<Result> ( long logId ) where Result : class
        {
            return this._BasicDAL.Get<Result>(logId);
        }

        public bool IsInProgress ( long appId, string linkType, long linkPk )
        {
            return this._BasicDAL.IsExists(a => a.AppId == appId && a.LinkType == linkType && a.LinkPk == linkPk && a.Status == FlowAuditLogStatus.进行中);
        }

        public AuditResult SaveAuditResult ( SaveAuditBody body )
        {
            return this._BasicDAL.SaveAuditResult(body);
        }

        public void Close ( DBFlowAuditLog log, long empId )
        {
            if ( log.Status == FlowAuditLogStatus.已结束 )
            {
                throw new ErrorException("flow.audit.already.end");
            }
            this._BasicDAL.Close(log, empId);
        }

        public bool CheckIsUse ( long flowId )
        {
            return this._BasicDAL.IsExists(c => c.FlowId == flowId);
        }
    }
}
